<?php
/**
 * Created by PhpStorm.
 * User: 97438
 * Date: 2019/9/18
 * Time: 11:43
 */

namespace app\model;

use think\facade\Cache;
use think\facade\Config;
use think\Model;

class VerifyCodeModel extends Model
{
    protected $name = 'verifyCode';
    protected $pk = 'verifyCodeId';
    const UN_VERIFIED = 0;
    const VERIFIED = 1;
    public $error = '';
    public $verifyTypeList = array(
        'regist' => 1,  //注册验证类型
    );

    /**
     * 生成验证码
     * @param int $len  验证码长度
     * @return string
     */
    private function generateCode($len = 6){
        $code = '';
        for($i=1;$i<=$len;$i++){
            $code .= rand(0,9);
        }
        return $code;
    }

    /**
     * 发送验证码
     * @param $mob
     * @param $type
     * @return array|void
     */
    public function send($mob,$type){
        if(!in_array($type,$this->verifyTypeList)){
            $this->error = '验证码生成失败';
            return;
        }
        if($type == $this->verifyTypeList['regist']){ //注册发送验证码判断
            $verifyType = $type;
            $userModel = new UserModel();
            $user = $userModel->getByMob($mob);
            if(!empty($user)){
                $this->error = '该手机号已被注册';
                return;
            }
        }
        $code = $this->generateCode();
        $data = array(
            'mob' => $mob,
            'verifyType' => $verifyType,
            'code' => $code,
            'sendTime' => date("Y-m-d H:i:s"),
            'outTime' => date("Y-m-d H:i:s",time()+Config::get('app.verifyCodeTimeOut')),
            'status' => VerifyCodeModel::UN_VERIFIED,
        );
        $verifyCodeInfo = $this->where(array('mob'=>$mob))->find();
        if(empty($verifyCodeInfo)){
            $codeInfo = $this->create($data);
        }else{
            if(time()-strtotime($verifyCodeInfo->sendTime)<Config::get('app.verifyCodeTimeSpan')){
                $this->error = '发送过于频繁，请稍后再试';
                return;
            }
            $codeInfo = $this->update($data,array('mob'=>$mob));
        }
        if(empty($codeInfo)){
            $this->error = '验证码生成失败';
            return;
        }
        //发送验证码短信

        return $codeInfo;
    }

    /**
     * 验证短信验证码
     * @param $mob
     * @param $code
     * @param $type
     * @return bool
     */
    public function verify($mob,$code,$type){
        if(!in_array($type,$this->verifyTypeList)){
            $this->error = '验证失败';
            return false;
        }
        $where = array(
            'mob' => $mob,
            'verifyType' => $type,
        );
        $verifyCode = $this->where($where)->find();
        if(empty($verifyCode)){
            $this->error = '请先获取短信验证码';
            return false;
        }
        if($verifyCode->status == VerifyCodeModel::VERIFIED || $verifyCode->code != $code){
            $this->error = '验证失败';
            //使用缓存限制连续失败次数
            $verifyCodeCache = Cache::get("verify:code:".$mob.":type:".$type);
            if(!empty($verifyCodeCache)){
                if($verifyCodeCache >= 20){
                    $this->error = '验证失败次数超限，请稍后再试！';
                    return false;
                }
                Cache::inc("verify:code:".$mob.":type:".$type,1);
            }else{
                Cache::set("verify:code:".$mob.":type:".$type,1,1800);
            }
            return false;
        }
        if($verifyCode->outTime < date("Y-m-d H:i:s")){
            $this->error = '验证码已过期';
            return false;
        }
        $verifyCode->status = VerifyCodeModel::VERIFIED;
        $verifyCode->save();
        Cache::delete("verify:code:".$mob.":type:".$type);
        return true;
    }
}